﻿using AngleSharp.Dom;
using DocumentFormat.OpenXml.Drawing.Charts;
using Microsoft.Extensions.Caching.Memory;

namespace AJWPFAdmin.Services
{
    public class BaseNonTableCache<TEntity> : IBaseNonTableCache<TEntity> where TEntity : class, new()
    {
        private readonly ICacheConfig<TEntity> _cacheConfig;
        private readonly IMemoryCache _cacheService;
        private readonly int _cacheDurationInSeconds;

        public BaseNonTableCache(ICacheConfig<TEntity> cacheConfig, IMemoryCache cacheService)
        {
            _cacheConfig = cacheConfig;
            _cacheService = cacheService;
        }

        public string GetStringCache(string cacheName = "")
        {
            var key = _cacheConfig.GetStringCacheKey();
            if (string.IsNullOrEmpty(cacheName))
                cacheName = key;
            var cache = _cacheService.Get<string>(cacheName);
            return cache;

        }

        public void SetStringCache(string targetVal, string cacheName = "", int cacheDurationInSeconds=0)
        {
            var key = _cacheConfig.GetStringCacheKey();
            if (string.IsNullOrEmpty(cacheName))
                cacheName = key;
            _cacheService.Set(cacheName, targetVal, new MemoryCacheEntryOptions().SetAbsoluteExpiration( DateTime.Now.AddSeconds(cacheDurationInSeconds)));
        }

        public async Task<string> GetOrSetStringCache(Func<Task<string>> getTargetValAsync, string cacheName="",int cacheDurationInSeconds = 0)
        {
            var key = _cacheConfig.GetStringCacheKey();
            if (string.IsNullOrEmpty(cacheName))
                cacheName = key;
            var cache = _cacheService.Get<string>(cacheName);
            if (string.IsNullOrEmpty(cache))
            {
                {
                    cache = await getTargetValAsync();
                    SetStringCache(cache, cacheName, cacheDurationInSeconds);
                }
            }
            return cache;
        }
        public List<TEntity> GetListCache(string cacheName = "")
        {
            var key = _cacheConfig.GetListCacheKey();
            if (string.IsNullOrEmpty(cacheName))
                cacheName = key;
            var cache = _cacheService.Get<List<TEntity>>(cacheName);
            return cache;

        }

        public async Task<List<TEntity>> GetOrSetListCache(Func<Task<List<TEntity>>> getListAsync, int cacheDurationInSeconds = 0,string cacheName = "")
        {
            var key = _cacheConfig.GetListCacheKey();
            if (string.IsNullOrEmpty(cacheName))
                cacheName = key;
            var ret = _cacheService.Get<List<TEntity>>(cacheName);
            if (ret == null || ret.Count == 0)
            {
                ret = await getListAsync();
                SetListCache(ret, cacheDurationInSeconds,cacheName);
            }
            return ret;
        }

        public List<TEntity> GetOrSetListCacheWithInnerCacheTime(Func<(List<TEntity>, int)> getList, string cacheName = "")
        {
            var key = _cacheConfig.GetListCacheKey();
            if (string.IsNullOrEmpty(cacheName))
                cacheName = key;
            var ret = _cacheService.Get<List<TEntity>>(cacheName);
            if (ret == null || ret.Count == 0)
            {
                var (a,b) = getList();
                ret = a;
                SetListCache(a,b, cacheName);
            }
            return ret;
        }


        public void SetListCache(List<TEntity> entity, int cacheDurationInSeconds=0,string cacheName = "")
        {
            var key = _cacheConfig.GetListCacheKey();
            if (string.IsNullOrEmpty(cacheName))
                cacheName = key;
            if (cacheDurationInSeconds != default)
            {
                _cacheService.Set(cacheName, entity, new MemoryCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(cacheDurationInSeconds)));
            }
            else
            {
                _cacheService.Set(cacheName, entity, new MemoryCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(cacheDurationInSeconds)));
            }
        }

        public void RemoveListCache(string cacheName)
        {
            var key = _cacheConfig.GetListCacheKey();
            if (string.IsNullOrEmpty(cacheName))
                cacheName = key;
            _cacheService.Remove(cacheName);
        }

    }
}
